package com.example.controller;

import com.alibaba.dashscope.app.Application;
import com.alibaba.dashscope.app.ApplicationParam;
import com.alibaba.dashscope.app.ApplicationResult;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.utils.Constants;
import com.example.service.VoiceServiceImpl;
import com.example.utils.AjaxResult;
import com.example.utils.SpeechToTextUtils;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import io.reactivex.Flowable;
import org.apache.tomcat.util.http.fileupload.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;

@RestController
@RequestMapping("/chatbot")
public class ChatbotController {
    @Value("${ai-key}")
    private String apiKey;

    @Autowired
    private VoiceServiceImpl voiceService;
    /**
     * 实现 chat 接口，支持流式返回数据
     *
     * @param query
     * @return
     */
    @RequestMapping(value = "/chat", method = RequestMethod.POST)
    public ResponseBodyEmitter streamData(@RequestBody String query) {
        ResponseBodyEmitter emitter = new ResponseBodyEmitter(180000L);

        Constants.apiKey = apiKey;
        JsonObject jsonObject = new JsonParser().parse(query).getAsJsonObject();
        try {
            streamCall(emitter, jsonObject.get("prompt").getAsString());
        } catch (NoApiKeyException | InputRequiredException e) {
            e.printStackTrace();
        }
        return emitter;
    }
    @RequestMapping("/speechToText")
    @ResponseBody
    public AjaxResult uploadFile(HttpServletRequest request){
        String fileFolder = System.getProperty("user.dir")+"/uploadFiles";
        try{
            request.setCharacterEncoding("utf-8");
            StandardMultipartHttpServletRequest req = (StandardMultipartHttpServletRequest) request;
            Iterator<String> iterator = req.getFileNames();

            File folder = new File(fileFolder);
            if(!folder.exists()) {
                folder.mkdirs();
            }
            List<String> filePaths = new ArrayList<>();
            while(iterator.hasNext()){
                MultipartFile multipartFile = req.getFile(iterator.next());
                String originalFirstName = multipartFile.getOriginalFilename();
                String uuid = UUID.randomUUID().toString().replace("-", "");
                String kzm = originalFirstName.substring(originalFirstName.lastIndexOf("."));
                String fileName = uuid + kzm;
                File file = new File(fileFolder + "/" + fileName);

                OutputStream out = new FileOutputStream(file);
                out.write(multipartFile.getBytes());
                out.close();
                filePaths.add(request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/uploadFiles/" + fileName);
                System.out.println("图片访问路径：" + filePaths);
            }
            String s = filePaths.get(0);

            return null;
        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.success("上传失败");
        }
    }



    /**
     * 调用百炼应用，封装流式返回数据
     * 返回数据格式
     * id:1
     * event:result
     * :HTTP_STATUS/200
     * data:{"output":{"session_id":"xxx","finish_reason":"null","text":"相关的问题"}}
     *
     * @param emitter
     * @param query
     * @throws NoApiKeyException
     * @throws InputRequiredException
     */
    public void streamCall(ResponseBodyEmitter emitter, String query) throws NoApiKeyException, InputRequiredException {
        // appId 填入百炼应用 ID
        ApplicationParam param = ApplicationParam.builder()
                .appId("c8645be3a70242d6a61fd5f8e0fc6503")
                .prompt(query)
                .incrementalOutput(true)
                .build();

        Application application = new Application();
        Flowable<ApplicationResult> result = application.streamCall(param);
        AtomicInteger counter = new AtomicInteger(0);
        result.blockingForEach(data -> {
            int newValue = counter.incrementAndGet();
            String resData = "id:" + newValue + "\nevent:result\n:HTTP_STATUS/200\ndata:" + new Gson().toJson(data) + "\n\n";
            emitter.send(resData.getBytes(java.nio.charset.StandardCharsets.UTF_8));

            if ("stop".equals(data.getOutput().getFinishReason())) {
                emitter.complete();
            }
        });

    }
}